
fn test_move() {
    let x = vec![1,2,3];

    let equal_x = move |z| z == x;
    // 不能打印，因为x被move到equal_x闭包中。
    // println!("cant use x, {:?}", x);
    let y = vec![1, 2, 3];
    assert!(equal_x(y));
}

// Fn特性保证其实现函数不会修改状态，可多次调用。
fn call_with_fn<F>(func: F) -> usize
    where F: Fn(usize) -> usize {
        func(1)
}

// FnOnce只能调用一次
fn call_once<F>(f: F) where F: FnOnce(usize)->usize {
    let a = 5;
    println!("a is: {}", f(a));
    // 调用不通过，因为a被move了
    // println!("a is: {}", f(a));
}

fn func() {
    let square = |x| x * x;
    assert_eq!(square(5), 25);
    assert_eq!(call_with_fn(square), 1);
    let a = 3;
    let c = move |x| x + a;
    call_once(c);
    call_once(c);
    c(3);
    println!("equals")
}

fn main() {
    // closure可以不指定参数类型。
    let mut a = 8;
    let mut c = |num: i32| {
            println!("calculating slowly...");
            a = 9;
            num
    };
    println!("Hello, world! {:?}", c(8));
    println!("Hello, world! a {:?}", a);

    func();
    test_move();
}
